/*
 * @Author: Wangjun
 * @Date: 2022-01-06 16:46:05
 * @LastEditTime: 2022-02-14 10:52:32
 * @LastEditors: Wangjun
 * @Description:
 * @FilePath: \plc_state_fand:\go\src\gitee.com\haodreams\golib\datachange\group.go
 * hnxr
 */
package datachange

import (
	"gitee.com/haodreams/golib/lz4file"
	"github.com/ugorji/go/codec"
)

type DataGroup struct {
	stringMap map[string]*DataChange
	intMap    map[int]*DataChange
	dcs       []*DataChange
	mems      []*Memory
	path      string
}

/**
 * @description: 生成一个datagroup
 * @param {string} path 内存数据保存的路径
 * @return {*}
 */
func NewDataGroup(path string) *DataGroup {
	dg := new(DataGroup)
	dg.Setup(path)
	return dg
}

/**
 * @description: 获取dataChange
 * @param {int} id
 * @return {*}
 */
func (m *DataGroup) GetDataChange(id int) (dc *DataChange) {
	dc = m.intMap[id]
	return dc
}

/**
 * @description: 初始化设置
 * @param {string} path 缓存文件保存的路径
 * @return {*}
 */
func (m *DataGroup) Setup(path string) {
	m.path = path
	m.dcs = nil
	m.mems = nil
	m.stringMap = map[string]*DataChange{}
	m.intMap = map[int]*DataChange{}
}

/**
 * @description: 添加一个数据变位事件
 * @param {*DataChange} dc
 * @return {*}
 */
func (m *DataGroup) Add(dc *DataChange) {
	m.dcs = append(m.dcs, dc)
}

/**
 * @description: 数据复位
 * @param {*}
 * @return {*}
 */
func (m *DataGroup) Reset() {
	m.dcs = nil
	m.mems = nil
	m.stringMap = map[string]*DataChange{}
	m.intMap = map[int]*DataChange{}
}

/**
 * @description: 更新内存的数据,并把文件中缓存的数据更新到内存
 * @param {*}
 * @return {*}
 */
func (m *DataGroup) Fresh() (err error) {
	m.mems = nil
	m.stringMap = map[string]*DataChange{}
	m.intMap = map[int]*DataChange{}

	for _, dc := range m.dcs {
		if dc != nil {
			m.stringMap[dc.Key] = dc
			m.intMap[dc.ID] = dc
			m.mems = append(m.mems, &dc.Memory)
		}
	}
	err = m.Load()
	return
}

/**
 * @description: 保存缓存的数据
 * @param {*}
 * @return {*}
 */
func (m *DataGroup) Save() (err error) {
	if len(m.mems) > 0 && m.path != "" {
		var data []byte
		mh := new(codec.MsgpackHandle)

		err = codec.NewEncoderBytes(&data, mh).Encode(&m.mems)
		if err != nil {

			return
		}

		err = lz4file.SaveLz4File(m.path, data)
		if err != nil {
			return
		}
	}
	return nil
}

/**
 * @description: 加载文件数据到内存,必须在Fresh之后使用
 * @param {*}
 * @return {*}
 */
func (m *DataGroup) Load() (err error) {
	if m.path == "" {
		return
	}

	if len(m.stringMap) == 0 {
		return
	}
	var mems []*Memory
	data, err := lz4file.LoadLz4File(m.path)
	if err != nil {
		return
	}
	mh := new(codec.MsgpackHandle)
	err = codec.NewDecoderBytes(data, mh).Decode(&mems)
	if err != nil {
		return
	}

	for _, mem := range mems {
		if mem == nil {
			continue
		}
		dc, ok := m.stringMap[mem.Key]
		if ok && dc != nil {
			dc.Memory = *mem
		}
	}

	return
}
